import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JProgressBar;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class CombatSkeleton extends JLayeredPane{

	// För att JPanel ska bli klad.
	private static final long serialVersionUID = 3541582192322513041L;
	JButton attack = new JButton("Attackera");
	JButton items = new JButton("Föremål");
	JButton flee = new JButton("Fly");
	JButton swap = new JButton("Byta");
	JButton up = new JButton("Upp");
	JButton down = new JButton("Ner");
	JButton map = new JButton("Tillbaka");
	JButton mainmenu = new JButton("Huvudmeny");
	JButton val = new JButton("Val");
	JPopupMenu popUpAttack = new JPopupMenu();
	JPopupMenu popUpItem = new JPopupMenu();
	JProgressBar xpBar = new JProgressBar();
	JProgressBar energyBar = new JProgressBar();
	JProgressBar hpBar1= new JProgressBar();
	JProgressBar hpBar2 = new JProgressBar();
	JLabel attackPlayerAnimation=new JLabel();
	JLabel attackEnemyAnimation=new JLabel();
	JLabel playerItemAnimation=new JLabel();
	JLabel enemyItemAnimation=new JLabel();
	JLabel playerPetImage = new JLabel();
	JLabel playerPetLevel = new JLabel();
	JLabel playerPetName = new JLabel();
	JLabel enemyPetImage = new JLabel();
	JLabel enemyPetLevel = new JLabel();
	JLabel enemyPetName = new JLabel();
	JLabel backGround = new JLabel();
	JLabel enemyType = new JLabel();
	JLabel playerType = new JLabel();
	JLabel background = new JLabel();
	ImageIcon nature = new ImageIcon(getClass().getResource("/Pics/natureIcon.gif"));
	ImageIcon fire = new ImageIcon(getClass().getResource("/Pics/fireIcon.gif"));
	ImageIcon water = new ImageIcon(getClass().getResource("/Pics/waterIcon.gif"));
	ImageIcon energy = new ImageIcon(getClass().getResource("/Pics/energyIcon.gif"));
	JTextArea textArea = new JTextArea();
	JMenuItem item1;
	JMenuItem item2;
	JMenuItem item3;
	JMenuItem item4;
	JMenuItem attack1;
	JMenuItem attack2;
	JMenuItem attack3;
	JMenuItem attack4;
	Color blue = new Color(0,191,255);
	Color orange = new Color(255,140,0);
	Color green = new Color(34,139,34);
	Color brighterGreen = green.brighter();
	Font font = new Font("Verdana", Font.PLAIN, 25);
	Font font2 = new Font("Verdana", Font.PLAIN, 18);
	String[][] inventoryLevels = new String[20][4];
    ArrayList<AttackName> listWithAttacks = new ArrayList<AttackName>();
    ArrayList<ItemKind> listWithItems = new ArrayList<ItemKind>();
    final int ENLARGE_VALUE = 100;
	protected int currentInventoryLevel = 0;
	protected int finalInventoryLevel = 0;
    Player player;
    Player enemy;
    JLayeredPane thispanel;
    private ConcurrentLinkedQueue<Action> actionQueue;
    public InterfaceFrame frame;
    private CombatEngine ce;
    boolean catchMode = false;
    boolean victoryMode = false;
    MapNode node;

    CombatSkeleton(Player player, Player enemy, InterfaceFrame frame, boolean catchAble, MapNode node){
    	UIManager.put("MenuItem.selectionBackground", new Color(163,184,204));
		UIManager.put("MenuItem.selectionForeground", Color.BLACK);
		UIManager.put("MenuItem.foreground", Color.BLACK);
		
		// Måste skapas här för att förändingarna ovan med UIManager.
		item1 = new JMenuItem();
		item2 = new JMenuItem();
		item3 = new JMenuItem();
		item4 = new JMenuItem();
		attack1 = new JMenuItem();
		attack2 = new JMenuItem();
		attack3 = new JMenuItem();
		attack4 = new JMenuItem();
		
		if(enemy.playerName.equals("BOSS"))
			victoryMode = true;
    	this.node = node;
    	this.frame = frame;
		thispanel = this;
		this.player=player;
		this.enemy=enemy;
		actionQueue = new ConcurrentLinkedQueue<Action>();
		listWithItems = player.inventory.getEffectItems();
		listWithAttacks = player.activePet.getAttacks();
		setLayout(null);
		setSize(frame.width, frame.height);
		addMouseListener(new OurMouseListener());
		addBackground();
		addItemAnimations();
		addButtons();
		addBars();
		addEnemy();
		addKeyBindings();
		addPlayer();
		createInventoryLevels();
		textArea.setText("\n\n\n\n\n\n\n\n"); // bestämmer hur många rader det är i arean hela tin
		frame.getContentPane().repaint();
		ce = new CombatEngine(player, (AI) enemy, this, actionQueue, catchAble, this.node); 
		ce.execute();
		
	}
    
    public void addBackground(){
    	
    	if(node.type.equals(TerrainType.City)){
			background = new JLabel("", new ImageIcon(getClass().getResource("/Pics/city.png")), JLabel.LEADING);
		}
		else if(node.type.equals(TerrainType.Village)){
			background = new JLabel("", new ImageIcon(getClass().getResource("/Pics/village.png")), JLabel.LEADING);
		}
		else if(node.type.equals(TerrainType.Forest)){
			background = new JLabel("", new ImageIcon(getClass().getResource("/Pics/thisShit.png")), JLabel.LEADING);
		}
		else if(node.type.equals(TerrainType.Field)){
			background = new JLabel("", new ImageIcon(getClass().getResource("/Pics/field.png")), JLabel.LEADING);
		}
		else if(node.type.equals(TerrainType.Mountains)){
			background = new JLabel("", new ImageIcon(getClass().getResource("/Pics/mounatins.png")), JLabel.LEADING);
		}
		else if(node.type.equals(TerrainType.Sand)){
			background = new JLabel("", new ImageIcon(getClass().getResource("/Pics/beach.gif")), JLabel.LEADING);
		}
		else if(node.type.equals(TerrainType.Lake)){
			background = new JLabel("", new ImageIcon(getClass().getResource("/Pics/lake.png")), JLabel.LEADING);
		}
		else{
			background = new JLabel("", new ImageIcon(getClass().getResource("/Pics/field.png")), JLabel.LEADING);
		}
    	
    	background.setBounds(0, 0, 1200, 676);
    	add(background, new Integer(0));
    }
    
    public ConcurrentLinkedQueue<Action> getActionQueue() {
    	return actionQueue;
    }
    
    public void closeCombatInterface() {
        frame.swapToWorldMap();
    }
    
    //Skapar en större array, behövs då vi inte vet hur många items spelaren har.
    private void enlarge(){
    	
    	int newLength = 1 + inventoryLevels.length + ENLARGE_VALUE * inventoryLevels.length/100;
    	String[][] newArray = new String[newLength][4];
    	
    	for(int index = 0; index < inventoryLevels.length; index++){
    		for(int j = 0; j < 4; j++)
    			newArray[index][j] = inventoryLevels[index][j];
    	}
    	
    	inventoryLevels = newArray;
    	
    }
    
    //Läger till en text till JLabeln mellan knapparna.
    public void displayAction(String str){
    	
    	textArea.setEditable(false);
    	String currentText = textArea.getText();
    	String newText = currentText.substring(currentText.indexOf('\n') + 1)
    			       + '\n' + str;
    	textArea.setText(newText);
    	textArea.setBounds(300, 437, 598, 211);
    	textArea.setFont(font2);
    	add(textArea, new Integer(3));

    }
    public void clearDisplay(){
    	textArea.setText("\n\n\n\n\n\n\n\n");
    	String currentText = textArea.getText();
    	String newText = currentText.substring(currentText.indexOf('\n') + 1)
    			       + '\n';
    	textArea.setText(newText);
    	
    }
    
    //Används för att slippa ha nummer med i displayAction panelen.
    public String removeItemCountFromString(String str){
		
    	//Kapar strängen vid första mellanslaget och returnerar den första delen.
		int index = str.indexOf(" ") + 1;
		String str1 = str.substring(index);
		
		return str1;
		
	}
    
    
    
    /*
     * Problemet med vårt inventory är att vi inte vet hur många items en spelare har iförväg.
     * Lösningen var att vi delade in alla föremål i "Levels" (String[]) där en Level max har 4st föremål.
     * Sen sparar vi dessa en en annan array "inventoryLevels" där vi sedan hämtar items ifrån beroende på
     * vilken lvl vi befinner oss i. Denna funktion skapar dessa Levels.
     */
    public void createInventoryLevels(){
    	
    	inventoryLevels = new String[20][4];
    	listWithItems = player.inventory.getEffectItems();
    	
    	//Undersöker vilken sista Leveln är.
    	if(listWithItems.size()%4 == 0)
    		finalInventoryLevel = listWithItems.size()/4 - 1;
    	else
    		finalInventoryLevel = listWithItems.size()/4;
    	
    	String level[] = new String[4];
    	int index = 0;
    	
    	for(int i = 0; i <= finalInventoryLevel; i++){
    		
    		//Om inventoryLevels arrayen är full, skapa en större!
    		if(inventoryLevels.length <= index)
    			enlarge();
    		
    		//Lopar fram en sträng till varje index som innehåller hur många items och namnet.
    		for(int j = 0; j < 4; j++){
    			
    			level[i] = player.inventory.itemCount(listWithItems.get(index)) + "x " + new Item(listWithItems.get(index)).getName();
    			inventoryLevels[i][j] = level[i];
    			index++;
    			
    			//Ifall vi kommit till slutet bryt.
    			if(index >= listWithItems.size()){
    				break;
    			}
    			
    		}
    		
    	}
    	
    }
    
    //Skriver texten som skapades i funktionen ovan och visar den på popup-menyn.
    public void showInventoryLevel(int level){
		
		if(inventoryLevels[level][0] != null)
			item1.setText(inventoryLevels[level][0]);
		if(inventoryLevels[level][1] != null)
			item2.setText(inventoryLevels[level][1]);
		if(inventoryLevels[level][2] != null)
			item3.setText(inventoryLevels[level][2]);
		if(inventoryLevels[level][3] != null)
			item4.setText(inventoryLevels[level][3]);
			
		if(inventoryLevels[level][0] != null)
			popUpItem.add(item1);
		else
			popUpItem.remove(item1);
		if(inventoryLevels[level][1] != null)
			popUpItem.add(item2);
		else
			popUpItem.remove(item2);
		if(inventoryLevels[level][2] != null)
			popUpItem.add(item3);
		else
			popUpItem.remove(item3);
		if(inventoryLevels[level][3] != null)
			popUpItem.add(item4);
		else
			popUpItem.remove(item4);
		
		popUpItem.setPopupSize(600,151);
		popUpItem.show(this, 299, 437);
		
		
	}
    
    public void addItemAnimations(){
    	playerItemAnimation.setBounds(45, 170, 256, 256);
        add(playerItemAnimation, new Integer(1));
        enemyItemAnimation.setBounds(924, 100, 60, 60);
        add(enemyItemAnimation, new Integer(1));
        attackPlayerAnimation.setBounds(307, 75, 600, 300);
        add(attackPlayerAnimation, new Integer(1));
        attackEnemyAnimation.setBounds(307, 75, 600, 300);
        add(attackEnemyAnimation, new Integer(1));
    }
    public void runPlayerItemAnimation(String path, int timeAnimation){
    	
    	ImageIcon itemAnimation=new ImageIcon(getClass().getResource(path));
		playerItemAnimation.setIcon(itemAnimation);
		itemAnimation.getImage().flush();
    	playerItemAnimation.setVisible(true);
    	new Timer().schedule(new TimerTask(){
    		public void run(){
    			playerItemAnimation.setVisible(false);
    			
    	   	 }
    	},timeAnimation);
    	
    }
    
    public void runEnemyItemAnimation(String path, int timeAnimation){
    	ImageIcon itemAnimation=new ImageIcon(getClass().getResource(path));
		enemyItemAnimation.setIcon(itemAnimation);
		itemAnimation.getImage().flush();
    	enemyItemAnimation.setVisible(true);
    	new Timer().schedule(new TimerTask(){
    		public void run(){
    			enemyItemAnimation.setVisible(false);
    	   	 }
    	},timeAnimation);
    	
    }
    
    public void runPlayerAttackAnimation(String path, int timeAnimation){
    	ImageIcon attackIconAnimation=new ImageIcon(getClass().getResource(path));
    	attackPlayerAnimation.setIcon(attackIconAnimation);
    	attackIconAnimation.getImage().flush();
    	attackPlayerAnimation.setVisible(true);
    	new Timer().schedule(new TimerTask(){
    		public void run(){
    			attackPlayerAnimation.setVisible(false);
    	   	 }
    	},timeAnimation);
    	
    }
    
    public void runEnemyAttackAnimation(String path, int timeAnimation){
    	ImageIcon attackIconAnimation=new ImageIcon(getClass().getResource(path));
    	attackEnemyAnimation.setIcon(attackIconAnimation);
    	attackIconAnimation.getImage().flush();
    	attackEnemyAnimation.setVisible(true);
    	new Timer().schedule(new TimerTask(){
    		public void run(){
    			attackEnemyAnimation.setVisible(false);
    	   	 }
    	},timeAnimation);
    	
    }
    
    public void addPlayer(){
		    	
		playerPetName.setBounds(130, 85, 220, 40);
		playerPetLevel.setBounds(40, 85, 80, 40);
		playerPetImage.setBounds(23, 170, 256, 256);
		
		playerPetName.setForeground(Color.RED);
		playerPetLevel.setForeground(Color.RED);
		
		playerType.setBounds(260, 120, 40, 40);
		
		if(player.activePet.element == Type.Energy)
			playerType.setIcon(energy);
		else if(player.activePet.element == Type.Nature)
			playerType.setIcon(nature);
		else if(player.activePet.element == Type.Water)
			playerType.setIcon(water);
		else if(player.activePet.element == Type.Fire)
			playerType.setIcon(fire);
		
		playerPetName.setFont(font2);
		playerPetLevel.setFont(font2);
		
		playerPetName.setText(player.activePet.getName());
		playerPetLevel.setText("Nivå: " + player.activePet.getCurrentLevel());
		playerPetImage.setIcon(new ImageIcon(getClass().getResource(player.activePet.backImage)));
		
		add(playerPetLevel, new Integer(1));
		add(playerPetImage, new Integer(1));
		add(playerPetName, new Integer(1));
		add(playerType, new Integer(1));
	}
    
    public void addEnemy(){
		
    	enemyPetName.setBounds(1030, 16, 220, 40);
    	enemyPetImage.setBounds(924, 100, 256, 256);
    	enemyPetLevel.setBounds(942, 16, 80, 40);
    	
    	enemyPetName.setForeground(Color.RED);
    	enemyPetLevel.setForeground(Color.RED);
    	
    	enemyType.setBounds(902, 50, 40, 40);
		
		if(enemy.activePet.element == Type.Energy)
			enemyType.setIcon(energy);
		else if(enemy.activePet.element == Type.Nature)
			enemyType.setIcon(nature);
		else if(enemy.activePet.element == Type.Water)
			enemyType.setIcon(water);
		else if(enemy.activePet.element == Type.Fire)
			enemyType.setIcon(fire);
    	
    	enemyPetName.setFont(font2);
    	enemyPetLevel.setFont(font2);
    	
    	enemyPetName.setText(enemy.activePet.getName());
    	enemyPetLevel.setText("Nivå: "+ enemy.activePet.getCurrentLevel());
		enemyPetImage.setIcon(new ImageIcon(getClass().getResource(enemy.activePet.frontImage)));
		    	
		add(enemyPetName, new Integer(1));
		add(enemyPetImage, new Integer(1));
		add(enemyPetLevel, new Integer(1));
		add(enemyType, new Integer(1));
		
	}
    
    public void addBars(){
    	
    	xpBar.setBounds(0, 403, 1195, 15);
    	energyBar.setBounds(0, 417, 1195, 20);
    	hpBar1.setBounds(40, 120, 220, 40);
    	hpBar2.setBounds(942, 50, 220, 40);
    	
    	hpBar1.setMaximum(player.activePet.getMaxHealth());
    	hpBar2.setMaximum(enemy.activePet.getMaxHealth());
    	
    	
    	double percent = 100 * player.activePet.getCurrentHealth() / player.activePet.getMaxHealth();
		if(percent >= 50)
			hpBar1.setForeground(brighterGreen);
		else if(percent <= 20)
			hpBar1.setForeground(Color.RED);
		else
			hpBar1.setForeground(new Color(255,215,0));
		
		percent = 100 * enemy.activePet.getCurrentHealth() / enemy.activePet.getMaxHealth();
		if(percent >= 50)
			hpBar2.setForeground(brighterGreen);
		else if(percent <= 20)
			hpBar2.setForeground(Color.RED);
		else
			hpBar2.setForeground(new Color(255,215,0));
		
		
    	xpBar.setValue((int)player.activePet.getCurrentXP()%100);
    	hpBar1.setValue((int)player.activePet.getCurrentHealth());
    	hpBar2.setValue((int)enemy.activePet.getCurrentHealth());
    	
    	xpBar.setForeground(blue);
    	energyBar.setForeground(orange);
    	hpBar1.setForeground(brighterGreen);
    	hpBar2.setForeground(brighterGreen);
    	
    	xpBar.setStringPainted(true);
    	energyBar.setStringPainted(true);
    	hpBar1.setStringPainted(true);
    	hpBar2.setStringPainted(true);
    	
    	xpBar.setString(Integer.toString(player.activePet.currentXP));
    	energyBar.setString(Integer.toString(energyBar.getValue()));
    	hpBar1.setString(Integer.toString(hpBar1.getValue()));
    	hpBar2.setString(Integer.toString(hpBar2.getValue()));
    	
    	add(xpBar, new Integer(1));
    	add(energyBar, new Integer(1));
		add(hpBar1, new Integer(1));
		add(hpBar2, new Integer(1));
			
    }
	
	public void updateXp(){
		xpBar.setValue((int)player.activePet.getCurrentXP()%100);
		xpBar.setString(Integer.toString((int)player.activePet.getCurrentXP()));
	}
	
	public void updateEnergy(){
		energyBar.setValue((int)player.activePet.energy);
		energyBar.setString(Integer.toString((int)player.activePet.energy));
	}
	
	public void updatePlayerHp(){
		double percent = 100 * player.activePet.getCurrentHealth() / player.activePet.getMaxHealth();
		if(percent >= 50)
			hpBar1.setForeground(brighterGreen);
		else if(percent <= 20)
			hpBar1.setForeground(Color.RED);
		else
			hpBar1.setForeground(new Color(255,215,0));

		hpBar1.setMaximum(player.activePet.getMaxHealth());
		hpBar1.setValue(player.activePet.getCurrentHealth());
		hpBar1.setString(Integer.toString(player.activePet.getCurrentHealth()));
	}
	
	public void updateEnemyHp(){
		double percent = 100 * enemy.activePet.getCurrentHealth() / enemy.activePet.getMaxHealth() ;
		if(percent >= 50)
			hpBar2.setForeground(brighterGreen);
		else if(percent <= 20)
			hpBar2.setForeground(Color.RED);
		else
			hpBar2.setForeground(new Color(255,215,0));
		
    	hpBar2.setMaximum(enemy.activePet.getMaxHealth());
		hpBar2.setValue(enemy.activePet.getCurrentHealth());
		hpBar2.setString(Integer.toString(enemy.activePet.getCurrentHealth()));
	}
	
	public void updatePics(){
		
		playerPetName.setText(player.activePet.getName());
		enemyPetName.setText(enemy.activePet.getName());
		playerPetLevel.setText("Nivå: " + Integer.toString(player.activePet.getCurrentLevel()));
		enemyPetLevel.setText("Nivå: " + Integer.toString(enemy.activePet.getCurrentLevel()));
		playerPetImage.setIcon(new ImageIcon(getClass().getResource(player.activePet.backImage)));
		enemyPetImage.setIcon(new ImageIcon(getClass().getResource(enemy.activePet.frontImage)));
		hpBar1.setValue(player.activePet.getCurrentHealth());
		hpBar2.setValue(enemy.activePet.getCurrentHealth());
		
		
	}
	
	public void update(){
		
		listWithAttacks = new ArrayList<AttackName>();
		listWithAttacks = player.activePet.attacks;
		listWithItems = new ArrayList<ItemKind>();
		listWithItems = player.inventory.getEffectItems();
		createInventoryLevels();
		updateEnergy();
		updatePlayerHp();
		updateEnemyHp();
		updateXp();
		updatePics();
		
		if(enemy.activePet.element == Type.Energy)
			enemyType.setIcon(energy);
		else if(enemy.activePet.element == Type.Nature)
			enemyType.setIcon(nature);
		else if(enemy.activePet.element == Type.Water)
			enemyType.setIcon(water);
		else if(enemy.activePet.element == Type.Fire)
			enemyType.setIcon(fire);
		
		if(player.activePet.element == Type.Energy)
			playerType.setIcon(energy);
		else if(player.activePet.element == Type.Nature)
			playerType.setIcon(nature);
		else if(player.activePet.element == Type.Water)
			playerType.setIcon(water);
		else if(player.activePet.element == Type.Fire)
			playerType.setIcon(fire);
		//textArea.setVisible(true);
		
	}
	
	public void closePopupMenus() {
		popUpItem.setVisible(false);
		popUpAttack.setVisible(false);
		up.setVisible(false);
		down.setVisible(false);
		textArea.setVisible(true);
	}
	
	/**
	 * TO DO
	 */
	
	public void addKeyBindings(){
		
		InputMap im = getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
	    ActionMap am = getActionMap();

	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0), "Attacks");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "Items");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_E, 0), "Switch");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0), "Flee");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0), "Pause");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "1");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_2, 0), "2");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_3, 0), "3");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_4, 0), "4");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD1, 0), "K1");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD2, 0), "K2");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD3, 0), "K3");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD4, 0), "K4");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.SHIFT_DOWN_MASK), "Down");
	    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.SHIFT_DOWN_MASK), "Up");

	    am.put("Attacks", new KeyAction("Attacks"));
	    am.put("Items", new KeyAction("Items"));
	    am.put("Switch", new KeyAction("Switch"));
	    am.put("Flee", new KeyAction("Flee"));
	    am.put("Pause", new KeyAction("Pause"));
	    am.put("Down", new KeyAction("Down"));
	    am.put("Up", new KeyAction("Up"));
	    am.put("1", new KeyAction("1"));
	    am.put("2", new KeyAction("2"));
	    am.put("3", new KeyAction("3"));
	    am.put("4", new KeyAction("4"));
	    am.put("K1", new KeyAction("K1"));
	    am.put("K2", new KeyAction("K2"));
	    am.put("K3", new KeyAction("K3"));
	    am.put("K4", new KeyAction("K4"));
	    
	}
	
	
	public void addButtons(){

		attack.setBounds(0, 437, 300, 106);
		items.setBounds(898, 437, 300, 106);
		swap.setBounds(0, 543, 300, 105);
		flee.setBounds(898, 543, 297, 105);
		map.setBounds(898, 543, 297, 105);
		mainmenu.setBounds(898, 543, 297, 105);
		val.setBounds(898, 543, 297, 105);
		up.setBounds(299,587,300,61);
		down.setBounds(599,587,301,61);
		
		swap.setBackground(Color.white);
		attack.setBackground(Color.white);
		items.setBackground(Color.white);
		flee.setBackground(Color.white);
		up.setBackground(Color.white);
		down.setBackground(Color.white);
		map.setBackground(Color.white);
		mainmenu.setBackground(Color.white);
		val.setBackground(Color.white);
		
		map.setFont(font);
		mainmenu.setFont(font);
		val.setFont(font);
		swap.setFont(font);
		attack.setFont(font);
		items.setFont(font);
		flee.setFont(font);
		up.setFont(font);
		down.setFont(font);
		item1.setFont(font);
		item2.setFont(font);
		item3.setFont(font);
		item4.setFont(font);
		attack1.setFont(font);
		attack2.setFont(font);
		attack3.setFont(font);
		attack4.setFont(font);
		
		add(swap, new Integer(1));
		add(items, new Integer(1));
		add(attack, new Integer(1));
		add(flee, new Integer(1));
		add(popUpAttack, new Integer(1));
		add(down, new Integer(5));
		add(up, new Integer(5));
		
		if(player.passivePet == null)
			swap.setEnabled(false);
		if(listWithItems.size() == 0)
			items.setEnabled(false);
		
		up.setMultiClickThreshhold(200);
		down.setMultiClickThreshhold(200);
		
		up.setVisible(false);
		down.setVisible(false);
		
		val.addActionListener(new ButtonListener());
		items.addActionListener(new ButtonListener());
		attack.addActionListener(new ButtonListener());
		flee.addActionListener(new ButtonListener());
		map.addActionListener(new ButtonListener());
		mainmenu.addActionListener(new ButtonListener());
		swap.addActionListener(new ButtonListener());
		up.addActionListener(new ButtonListener());
		down.addActionListener(new ButtonListener());
		down.addMouseListener(new OurMouseListener());
		up.addMouseListener(new OurMouseListener());
		items.addMouseListener(new OurMouseListener());
		attack.addMouseListener(new OurMouseListener());
		flee.addMouseListener(new OurMouseListener());
		swap.addMouseListener(new OurMouseListener());
		item1.addActionListener(new ButtonListener());
		item2.addActionListener(new ButtonListener());
		item3.addActionListener(new ButtonListener());
		item4.addActionListener(new ButtonListener());
		attack1.addActionListener(new ButtonListener());
		attack2.addActionListener(new ButtonListener());
		attack3.addActionListener(new ButtonListener());
		attack4.addActionListener(new ButtonListener());
		val.addMouseListener(new OurMouseListener());
		popUpItem.addPopupMenuListener(new MyPopupMenuListener());
	}
	
	private class OurMouseListener implements MouseListener{

		@Override
		public void mouseClicked(MouseEvent e) {
		}

		@Override
		public void mouseEntered(MouseEvent e) {
		}

		@Override
		public void mouseExited(MouseEvent e) {
		}
		
		@Override
		public void mousePressed(MouseEvent e) {
			textArea.setVisible(true);
			
			if(!popUpItem.isVisible()){
				up.setVisible(false);
				down.setVisible(false);
				down.setEnabled(true);	
			}
			else
				popUpItem.requestFocus();
			
		}

		@Override
		public void mouseReleased(MouseEvent e) {
		}

	}
	
	//Lyssnare för alla knappar!
	class ButtonListener implements ActionListener{
		
		@Override
		public void actionPerformed(ActionEvent e) {
			
			if(e.getSource().equals(val)){
				attack1.setText("Ersätt aktivt husdjur");
				attack2.setText("Ersätt passivt husdjur");
				attack3.setText("Ångra dig");
				
				popUpAttack.add(attack1);
				popUpAttack.add(attack2);
				popUpAttack.add(attack3);
				
				popUpAttack.setPopupSize(600,211);
				popUpAttack.show(thispanel, 299, 437);
			}
			
			else if(e.getSource().equals(attack)){
				textArea.setVisible(false);
				if(listWithAttacks.size() > 0){
					attack1.setText(new Attack(listWithAttacks.get(0)).getEnergyCost() + " " + new Attack(listWithAttacks.get(0)).getName());
					textArea.setVisible(true);
				}else
					attack1.setText("<EMPTY>");
				if(listWithAttacks.size() > 1){
					attack2.setText(new Attack(listWithAttacks.get(1)).getEnergyCost() + " " + new Attack(listWithAttacks.get(1)).getName());
					textArea.setVisible(true);
				}else
					attack2.setText("<EMPTY>");
				if(listWithAttacks.size() > 2){
					attack3.setText(new Attack(listWithAttacks.get(2)).getEnergyCost() + " " + new Attack(listWithAttacks.get(2)).getName());
				textArea.setVisible(true);
				}else
					attack3.setText("<EMPTY>");
				if(listWithAttacks.size() > 3){
					attack4.setText(new Attack(listWithAttacks.get(3)).getEnergyCost() + " " + new Attack(listWithAttacks.get(3)).getName());
				textArea.setVisible(true);
				}else
					attack4.setText("<EMPTY>");
				
				if(!attack1.getText().equals("<EMPTY>"))
					popUpAttack.add(attack1);
				else
					popUpAttack.remove(attack1);
				if(!attack2.getText().equals("<EMPTY>"))
					popUpAttack.add(attack2);
				else
					popUpAttack.remove(attack2);
				if(!attack3.getText().equals("<EMPTY>"))
					popUpAttack.add(attack3);
				else
					popUpAttack.remove(attack3);
				if(!attack4.getText().equals("<EMPTY>"))
					popUpAttack.add(attack4);
				else
					popUpAttack.remove(attack4);
				
				popUpAttack.setPopupSize(600,211);
				popUpAttack.show(thispanel, 299, 437);
				down.setEnabled(true);
			}
				
			else if(e.getSource().equals(items)){
					
				listWithItems = new ArrayList<ItemKind>();
				listWithItems = player.inventory.getEffectItems();
				currentInventoryLevel = 0;
				showInventoryLevel(currentInventoryLevel);
				down.setVisible(true);
				down.setEnabled(true);
				//textArea.setVisible(false);
				up.setEnabled(false);
				up.setVisible(true);
				if(listWithItems.size() <= 4)
					down.setEnabled(false);
			}
			else if(e.getSource().equals(flee) && flee.getText().equals("Fly")){

				actionQueue.add(new Flee());
				popUpItem.setVisible(false);
				popUpAttack.setVisible(false);

			}
			else if(e.getSource().equals(flee) && flee.getText().equals("Tillbaka")){
				frame.getContentPane().repaint();
				frame.swapToNodeInterface(player.nodeIndex, false);
			}
			
			else if(e.getSource().equals(map) ){
				frame.getContentPane().repaint();
				frame.swapToNodeInterface(player.nodeIndex, false);

			}
			else if(e.getSource().equals(mainmenu)){
				frame.getContentPane().repaint();
				frame.swapToStartMenu();

			}
			else if(e.getSource().equals(swap) && swap.getText().equals("Byta")){
				
				actionQueue.add(new SwapPet());
				down.setEnabled(true);
				
			}
			else if(e.getSource().equals(swap) && swap.getText().equals("Huvudmenyn")){
				frame.getContentPane().repaint();
				frame.swapToStartMenu();

			}
				
			else if(e.getSource().equals(down)){
				
				currentInventoryLevel++;
				showInventoryLevel(currentInventoryLevel);
				up.setVisible(true);
				up.setEnabled(true);
				
				if(currentInventoryLevel >= finalInventoryLevel){
					down.setEnabled(false);
				}
			}
				
			else if(e.getSource().equals(up)){
				
				currentInventoryLevel--;
				showInventoryLevel(currentInventoryLevel);
				down.setVisible(true);
				down.setEnabled(true);
				
				if(currentInventoryLevel == 0){
					up.setEnabled(false);
				}
					
			}
			
			else if(e.getSource().equals(item1) && listWithItems.size() >= 1){
				
				int index = currentInventoryLevel * 4;
				up.setVisible(false);
				down.setVisible(false);
				textArea.setVisible(true);
				//runPlayerItemAnimation(new Item(listWithItems.get(index)).getAnimation());
				actionQueue.add(new UseItem(listWithItems.get(index)));
			}
			else if(e.getSource().equals(item2) && listWithItems.size() >= 2){
				
				int index = currentInventoryLevel * 4 + 1;
				up.setVisible(false);
				down.setVisible(false);
				textArea.setVisible(true);
				//runPlayerItemAnimation(new Item(listWithItems.get(index)).getAnimation());
				actionQueue.add(new UseItem(listWithItems.get(index)));
			}
			else if(e.getSource().equals(item3) && listWithItems.size() >= 3){
				
				int index = currentInventoryLevel * 4 + 2;
				up.setVisible(false);
				down.setVisible(false);
				textArea.setVisible(true);
				//runPlayerItemAnimation(new Item(listWithItems.get(index)).getAnimation());
				actionQueue.add(new UseItem(listWithItems.get(index)));
			}
			else if(e.getSource().equals(item4) && listWithItems.size() >= 4){
				
				int index = currentInventoryLevel * 4 + 3;
				up.setVisible(false);
				down.setVisible(false);
				textArea.setVisible(true);
				//runPlayerItemAnimation(new Item(listWithItems.get(index)).getAnimation());
				actionQueue.add(new UseItem(listWithItems.get(index)));
			}

			else if(e.getSource().equals(attack1) && catchMode){
				displayAction("Du ersatte " + player.activePet.name + " med " + enemy.activePet.name);
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e1) {
					throw new RuntimeException(e1);
				}
				player.activePet = ce.enemyPet;
				for(int i = 0; i < ce.currentPlayer.passivePet.attacks.size(); i++)
					player.spellBook.addItem(ce.currentPlayer.passivePet.attacks.get(i));
				frame.getContentPane().repaint();
				frame.swapToNodeInterface(player.nodeIndex, true);
			}
			else if(e.getSource().equals(attack2) && catchMode){
				displayAction("Du ersatte " + player.passivePet.name + " med " + enemy.activePet.name);
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e2) {
					throw new RuntimeException(e2);
				}
				player.passivePet = ce.enemyPet;;
				for(int i = 0; i < ce.currentPlayer.passivePet.attacks.size(); i++)
					player.spellBook.addItem(ce.currentPlayer.passivePet.attacks.get(i));
				frame.getContentPane().repaint();
				frame.swapToNodeInterface(player.nodeIndex, true);
			}
			else if(e.getSource().equals(attack3) && catchMode){
				displayAction("Du släppte " + enemy.activePet.name + " lös");
				frame.getContentPane().repaint();
				frame.swapToNodeInterface(player.nodeIndex, false);
			}
			
			else if(e.getSource().equals(attack1) && listWithAttacks.size() >= 1){
				actionQueue.add(new UseAttack(listWithAttacks.get(0)));
				
			}
			else if(e.getSource().equals(attack2) && listWithAttacks.size() >= 2){
				actionQueue.add(new UseAttack(listWithAttacks.get(1)));
				
			}
			else if(e.getSource().equals(attack3) && listWithAttacks.size() >= 3){
				actionQueue.add(new UseAttack(listWithAttacks.get(2)));
				
			}
			else if(e.getSource().equals(attack4) && listWithAttacks.size() >= 4){
				actionQueue.add(new UseAttack(listWithAttacks.get(3)));
			}
				
		}
			
	}
	private class KeyAction extends AbstractAction{
		

	    private String cmd;

	    KeyAction(String cmd) {
	        this.cmd = cmd;
	    }
		
		private static final long serialVersionUID = 1L;

		@Override
		public void actionPerformed(ActionEvent arg0) {
			
			if(cmd.equals("Attacks"))
				attack.doClick();
			else if(cmd.equals("Items"))
				items.doClick();
			else if(cmd.equals("Switch"))
				swap.doClick();
			else if(cmd.equals("Flee"))
				flee.doClick();
			else if(cmd.equals("Pause"))
				actionQueue.add(new Pause());
			else if(cmd.equals("Down") && popUpItem.isVisible())
				down.doClick();
			else if(cmd.equals("Up") && popUpItem.isVisible())
				up.doClick();
			else if(cmd.equals("1") || cmd.equals("K1")){
				attack1.doClick();
				popUpAttack.setVisible(false);
			}
			else if((cmd.equals("2") || cmd.equals("K2")) && !attack2.getText().equals("<EMPTY>")){
				attack2.doClick();
				popUpAttack.setVisible(false);
			}
			else if((cmd.equals("3") || cmd.equals("K3")) && !attack3.getText().equals("<EMPTY>")){
				attack3.doClick();
				popUpAttack.setVisible(false);
			}
			else if((cmd.equals("4") || cmd.equals("K4")) && !attack4.getText().equals("<EMPTY>")){
				attack4.doClick();
				popUpAttack.setVisible(false);
			}
		}
	}
	
	public void startCredits(){
		new CreditsTimer();
	}
	public class CreditsTimer {
		 
	       
		CreditsTimer(){
			
		//1- Taking an instance of Timer class.
	    Timer timer = new Timer("Credits");
	 
        //2- Taking an instance of class contains your repeated method.
        MyTask t = new MyTask();
        
 
 
        //TimerTask is a class implements Runnable interface so
        //You have to override run method with your certain code black
 
        //Second Parameter is the specified the Starting Time for your timer in
        //MilliSeconds or Date
 
        //Third Parameter is the specified the Period between consecutive
        //calling for the method.
 
        timer.schedule(t, 0, 500);
	 
	    }
	}
	 
	class MyTask extends TimerTask {
	    //times member represent calling times.
	    private int times = 0;
	    String credits[] = {""
	    					,"Grattis!!!"
	    					,""
	    					,"Du har klarat spelet, räddat dagen och ätit kakan!"
	    					,""
	    					,"Project IT (ID1003) - 2013"
	    					,""
	    					,"Grupp 3"
	    					,""
	    					,"Medlemmar:"
	    					,"Björn Annegren"
	    					,"Christoffer Stjernlöf"
	    					,"Lukas Levin"
	    					,"Daniel Ulug"
	    					,"Johan Waller"
	    					,"Ville Granfors"
	    					,"Pontus Engström"
	    					,"Antonio Grondowski"
	    					,""
	    					,"Gruppledare:"
	    					,"Lukas Levin"
	    					,""
	    					,"Kunder:"
	    					,"Pontus Engström - Design"
	    					,"Ville Granfors - Karta"
	    					,"Antonio Grondowski - Strid"
	    					,"Daniel Ulug - Balans"
	    					,""
	    					,"Versionshantering:"
	    					,"Git"
	    					,""
	    					,"Process"
	    					,"Scrum"
	    					,""
	    					,"Klicka på Huvdmeny för att starta ett nytt spel"
	    					,"Eller Tillbaka för GameMode+"};
	 
	    public void run() {
	        times++;
	        if (times < credits.length) {
	            displayAction(credits[times]);
	        } else {
	        //Stop Timer.
	        this.cancel();
	        }
	    }
	}
	class MyPopupMenuListener implements PopupMenuListener {
		  public void popupMenuCanceled(PopupMenuEvent popupMenuEvent) {
			  up.setVisible(false);
			  down.setVisible(false);
			  frame.getContentPane().repaint();
		  }

		  public void popupMenuWillBecomeInvisible(PopupMenuEvent popupMenuEvent) {
		  }

		  public void popupMenuWillBecomeVisible(PopupMenuEvent popupMenuEvent) {
		  }
	}
}
